Having a switch
and its cases wholly encompassed by a control structure such as a try
, @try
,
catch
, @catch
, or a loop is perfectly acceptable. (try
and catch
are used hereafter to refer to
both variants.) It is also acceptable to have a goto
and its target label wholly encompassed in a control structure.
What is not acceptable is using a goto
or case
to suddenly jump into the body of a try
, catch
,
Objective-C @finally
, or loop structure. Tangling labels or switch
blocks with other control structures results in code that
is difficult, if not impossible to understand. More importantly, when it compiles (some of these constructs won’t compile under ISO-conformant
compilers), it can lead to unexpected results. Therefore this usage should be strictly avoided.
This C++ code sample, which is also applicable to Objective-C if try
and catch
are converted to @try
and
@catch
, demonstrates jumping into a switch
and into a try
and catch
:
Noncompliant code example
void f ( int32_t i )
{
if ( 10 == i )
{
goto Label_10; // Noncompliant; goto transfers control into try block
}
if ( 11 == i )
{
goto Label_11; // Noncompliant; goto transfers control into catch block
}
switch ( i )
{
case 1:
try
{
Label_10:
case 2: // Noncompliant; switch transfers control into try block
// Action
break;
}
catch ( ... )
{
Label_11:
case 3: // Noncompliant; switch transfers control into catch block
// Action
break;
}
break;
default:
{
// Default Action
break;
}
}
}
Compliant solution
void f ( int32_t i )
{
switch ( i )
{
case 1:
case 2:
// Action
break;
case 3:
// Action
break;
case 10:
default:
{
// Default Action
break;
}
}
try
{
if ( 2 == i || 10 == i)
{
// Action
}
}
catch ( ... )
{
if (3 == i || 11 == i)
{
// Action
}
}
}